`include "../Sys_Param.vh"
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2017/09/07 15:26:00
// Design Name: 
// Module Name: udp_transmit_test_1g
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
// function 
/*
1、实现ping包和ARP包功能；
// 2、本地IP地址和端口号可动态配置；
// 3、目的IP地址和端口号可动态配置；

*/
//////////////////////////////////////////////////////////////////////////////////


module udp_protocol_stack
(		
    input clk_15_625,    // 15.625M
    input independent_clock_bufg,
    // input clk_100,
		// input clk_200,		
		// input clk_15_625,
		input rst_n,				//  Active Low
		input gtrefclk1_p,
		input gtrefclk1_n,	
		
		input rx_p,
		input rx_n,		
		output wire tx_p,
		output wire tx_n,		

		output wire phy_resetn,
    inout phy_mdio,
    output phy_mdc,

		output wire [1:0]  Link_status,
		output reg udp_error_flag,
		input  mmcm_locked,
		
		output wire core_reset,							// Active High
				
		input wire [15:0]app_tx_data_length,
		
		output reg rx_udp_data_error_o,
		output reg [15:0]rx_udp_data_length_o,
		output reg [15:0]rx_udp_src_port_o,
//UDP RX
		output wire app_rx_data_valid,
		output wire [63:0] app_rx_data,
		output wire [7:0] app_rx_data_keep,
		output wire app_rx_data_last,
		
//UDP TX
		input wire app_tx_data_request,
		input wire app_tx_data_valid,
		input wire [63:0] app_tx_data,
		input wire [7:0] app_tx_data_keep,
		input wire app_tx_data_last,

		output wire udp_tx_ready,
		output wire app_tx_ack,
		output wire dst_ip_unreachable
    );

////////////////////////  mac_pll  ////////////////////////

wire reset;
assign reset = ~rst_n;


wire        mac_tx_valid;
wire [63:0] mac_tx_data;
wire [7:0]  mac_tx_keep;
wire        mac_tx_ready;
wire 		  	mac_tx_last;
wire			  mac_tx_user;
		
wire     		mac_rx_valid;
wire [63:0] mac_rx_data;
wire [7:0]  mac_rx_keep;
wire      	mac_rx_last;
wire      	mac_rx_user;
		
wire     		m_axis_tvalid1;
wire [63:0] m_axis_tdata1;
wire [7:0]  m_axis_tkeep1;
wire        m_axis_tready1;
wire      	m_axis_tlast1;
wire      	m_axis_tuser1;

wire        m_axis_tvalid2;
wire [63:0] m_axis_tdata2;
wire [7:0]  m_axis_tkeep2;
wire        m_axis_tready2;
wire 		  	m_axis_tlast2;
wire			  m_axis_tuser2;
		
wire     		m_axis_tvalid3;
wire [63:0] m_axis_tdata3;
wire [7:0]  m_axis_tkeep3;
wire        m_axis_tready3;
wire      	m_axis_tlast3;
wire        m_axis_tuser3;

wire        m_axis_tvalid4;
wire [63:0] m_axis_tdata4;
wire [7:0]  m_axis_tkeep4;
wire        m_axis_tready4;
wire 		  	m_axis_tlast4;
wire			  m_axis_tuser4;


wire [7:0]	gmii_txd;
wire        gmii_tx_en;
wire        gmii_tx_er;
wire [7:0]	gmii_rxd;
wire        gmii_rx_dv;
wire        gmii_rx_er;


wire        rx_mac_aclk;    // MAC Rx clock
wire        tx_mac_aclk;    // MAC Tx clock


// MAC receiver client I/F
wire [7:0]  rx_axis_mac_tdata;
wire        rx_axis_mac_tvalid;
wire        rx_axis_mac_tlast;
wire        rx_axis_mac_tuser;

// MAC transmitter client I/F
wire [7:0]  tx_axis_mac_tdata;
wire        tx_axis_mac_tvalid;
wire        tx_axis_mac_tready;
wire        tx_axis_mac_tlast;
wire        tx_axis_mac_tuser;



// AXI-Lite interface
wire  [11:0]         s_axi_awaddr;
wire                 s_axi_awvalid;
wire                 s_axi_awready;
wire  [31:0]         s_axi_wdata;
wire                 s_axi_wvalid;
wire                 s_axi_wready;
wire  [1:0]          s_axi_bresp;
wire                 s_axi_bvalid;
wire                 s_axi_bready;
wire  [11:0]         s_axi_araddr;
wire                 s_axi_arvalid;
wire                 s_axi_arready;
wire  [31:0]         s_axi_rdata;
wire  [1:0]          s_axi_rresp;
wire                 s_axi_rvalid;
wire                 s_axi_rready;




reg [15:0]  delay_cnt;
//wire        dst_ip_unreachable;

wire        tx_reset;
wire        rx_reset;

wire        glbl_rst_intn;     
wire 	      gtx_resetn;  
wire 	      s_axi_resetn;

wire [4:0]  configuration_vector;

wire        an_interrupt;
wire [15:0] an_adv_config_vector;
wire        an_restart_config;
wire        signal_detect;
wire [15:0] status_vector;

wire       userclk2;
wire       udp_rx_error;


//wire [1:0]	Link_status;
assign Link_status[0] = status_vector[0];  //link status
assign Link_status[1] = status_vector[1];  //Link Synchronization


assign  signal_detect = 1'b1;
assign  an_adv_config_vector = 16'b1001_1000_0000_0001;	// SGMII
//assign  an_adv_config_vector = 16'b0000_0000_0010_0000;		// 1000BASEX 		
assign  an_restart_config    = 1'b0;

assign  configuration_vector[1:0] = 2'h0;   // Disable Loopback
assign  configuration_vector[2]   = 1'b0;   // Disable POWERDOWN
assign  configuration_vector[3]   = 1'b0;   // Disable ISOLATE
assign  configuration_vector[4]   = 1'b1;   // Enable  Auto-Neg


//wire 	core_reset;
always @(posedge clk_15_625)
   begin
		if(core_reset) 
		  udp_error_flag <= 1'b0;
	  else if(udp_rx_error)
		  udp_error_flag <= 1'b1;
	  else
		  udp_error_flag <= udp_error_flag;
	end




tri_mode_ethernet_mac_0_example_design_resets example_resets
 (
// clocks
	.s_axi_aclk       (userclk2),
	.gtx_clk          (userclk2),
	.core_clk         (clk_15_625),
// asynchronous resets
	.glbl_rst         (reset),
	.reset_error      (1'b0),
	.rx_reset         (rx_reset),
	.tx_reset         (tx_reset),
	.dcm_locked       (mmcm_locked),
// synchronous reset outputs
	.glbl_rst_intn    (glbl_rst_intn),
	.gtx_resetn       (gtx_resetn),
	.s_axi_resetn     (s_axi_resetn),
	.phy_resetn       (phy_resetn),
	.chk_resetn       (),
	.core_reset       (core_reset)
 );


		
wire rx_udp_data_error;
wire [15:0] rx_udp_data_length;
wire [15:0] rx_udp_src_port;
wire ip_rx_error;
	



	
udp_ip_protocol_stack udp_ip_protocol_stack
(
  .ICMP_EN (`ICMP_EN),
  .ARP_REPLY_EN (`ARP_REPLY_EN),
  .ARP_REQUEST_EN (`ARP_REQUEST_EN),
  .ARP_TIMEOUT_VALUE (`ARP_TIMEOUT_VALUE),
  .ARP_RETRY_NUM (`ARP_RETRY_NUM),

  .LOCAL_PORT_NUM (`LOC_PORT_NUM),	 
  .LOCAL_IP_ADDRESS (`LOC_IP_ADDRESS),
  .LOCAL_MAC_ADDRESS (`LOC_MAC_ADDRESS),
  //    TX
  .app_tx_dst_port (`DST_UDP_PORT),
  .ip_tx_dst_address (`DST_IP_ADDRESS),
  .app_tx_data_length (app_tx_data_length), 
  //		RX
  .app_rx_data_length	(rx_udp_data_length), //	output
  .app_rx_port_num (rx_udp_src_port),		//	output
  .udp_rx_error (rx_udp_data_error),				//	output

  .core_clk (clk_15_625),	
  .reset (core_reset), 
  .udp_tx_ready (udp_tx_ready), 
  .app_tx_ack (app_tx_ack), 
  .app_tx_request (app_tx_data_request), //app_tx_data_request
  .app_tx_data_valid (app_tx_data_valid),	
  .app_tx_data (app_tx_data),
  .app_tx_data_keep (app_tx_data_keep),
  .app_tx_data_last (app_tx_data_last),	


  .app_rx_data_valid (app_rx_data_valid), 
  .app_rx_data (app_rx_data),
  .app_rx_data_keep (app_rx_data_keep),
  .app_rx_data_last (app_rx_data_last),



  .mac_tx_data_valid (mac_tx_valid),
  .mac_tx_data (mac_tx_data),
  .mac_tx_keep (mac_tx_keep),
  .mac_tx_ready (mac_tx_ready),
  .mac_tx_last (mac_tx_last),
  .mac_tx_user (mac_tx_user),		
  .mac_rx_data_valid (mac_rx_valid),
  .mac_rx_data (mac_rx_data),
  .mac_rx_keep (mac_rx_keep),
  .mac_rx_last (mac_rx_last),
  .mac_rx_user (1'b0),
  .ip_rx_error (ip_rx_error),	
  .dst_ip_unreachable (dst_ip_unreachable)
    );
    

always @ (posedge clk_15_625)
	begin
	if(core_reset)
		begin
		rx_udp_data_error_o <= 1'b0;
		rx_udp_data_length_o <= 16'b0;
		rx_udp_src_port_o <= 16'b0;
		end
	else if(app_rx_data_valid)
		begin
		rx_udp_data_error_o <= rx_udp_data_error;
		rx_udp_data_length_o <= rx_udp_data_length;
		rx_udp_src_port_o <= rx_udp_src_port;		
		end
	else
		begin
		rx_udp_data_error_o <= rx_udp_data_error_o;
		rx_udp_data_length_o <= rx_udp_data_length_o;
		rx_udp_src_port_o <= rx_udp_src_port_o;	
		end
	end

    
    
    

//////////////////////////////////////////////////////////////////////////////// 
////////////////////////////////   RX CHANNEL  //////////////////////////////// 
///////////////////////////////////////////////////////////////////////////////

axis_data_fifo_1 tx_async_fifo0 ////////////////////////////////   TX1
(
  .s_axis_aresetn(~core_reset),          // input wire s_axis_aresetn
  // .m_axis_aresetn(gtx_resetn),          // input wire m_axis_aresetn
  .s_axis_aclk(clk_15_625),                // input wire s_axis_aclk
  .s_axis_tvalid(mac_tx_valid),            // input wire s_axis_tvalid
  .s_axis_tready(mac_tx_ready),            // output wire s_axis_tready
  .s_axis_tdata(mac_tx_data),              // input wire [63 : 0] s_axis_tdata
  .s_axis_tkeep(mac_tx_keep),              // input wire [7 : 0] s_axis_tkeep
  .s_axis_tlast(mac_tx_last),              // input wire s_axis_tlast
  .s_axis_tuser(1'b0),              // input wire [0 : 0] s_axis_tuser
  .m_axis_aclk(tx_mac_aclk),                // input wire m_axis_aclk
  .m_axis_tvalid(m_axis_tvalid1),            // output wire m_axis_tvalid
  .m_axis_tready(m_axis_tready1),            // input wire m_axis_tready
  .m_axis_tdata(m_axis_tdata1),              // output wire [63 : 0] m_axis_tdata
  .m_axis_tkeep(m_axis_tkeep1),              // output wire [7 : 0] m_axis_tkeep
  .m_axis_tlast(m_axis_tlast1),              // output wire m_axis_tlast
  .m_axis_tuser(),                          // output wire [0 : 0] m_axis_tuser
  // .axis_data_count(),        // output wire [31 : 0] axis_data_count
  .axis_wr_data_count(),  // output wire [31 : 0] axis_wr_data_count
  .axis_rd_data_count()  // output wire [31 : 0] axis_rd_data_count
);
	
axis_data_fifo_0 tx_packet_fifo0 ////////////////////////////////   TX2
(
  .s_axis_aresetn(gtx_resetn),          // input wire s_axis_aresetn
  .s_axis_aclk(tx_mac_aclk),                // input wire s_axis_aclk
  .s_axis_tvalid(m_axis_tvalid1),            // input wire s_axis_tvalid
  .s_axis_tready(m_axis_tready1),            // output wire s_axis_tready
  .s_axis_tdata(m_axis_tdata1),              // input wire [63 : 0] s_axis_tdata
  .s_axis_tkeep(m_axis_tkeep1),              // input wire [7 : 0] s_axis_tkeep
  .s_axis_tlast(m_axis_tlast1),              // input wire s_axis_tlast
  .s_axis_tuser(1'b0),              // input wire [0 : 0] s_axis_tuser
  .m_axis_tvalid(m_axis_tvalid2),            // output wire m_axis_tvalid
  .m_axis_tready(m_axis_tready2),            // input wire m_axis_tready
  .m_axis_tdata(m_axis_tdata2),              // output wire [63 : 0] m_axis_tdata
  .m_axis_tkeep(m_axis_tkeep2),              // output wire [7 : 0] m_axis_tkeep
  .m_axis_tlast(m_axis_tlast2),              // output wire m_axis_tlast
  .m_axis_tuser(),                          // output wire [0 : 0] m_axis_tuser
  // .axis_data_count(),        // output wire [31 : 0] axis_data_count
  .axis_wr_data_count(),  // output wire [31 : 0] axis_wr_data_count
  .axis_rd_data_count()  // output wire [31 : 0] axis_rd_data_count
);	
	
axis_dwidth_converter_0 tx_axis_dwidth_converter0   ////////////////////////////////   TX3
(
  .aclk(tx_mac_aclk),                    // input wire aclk
  .aresetn(gtx_resetn),              // input wire aresetn
  .s_axis_tvalid(m_axis_tvalid2),  // input wire s_axis_tvalid
  .s_axis_tready(m_axis_tready2),  // output wire s_axis_tready
  .s_axis_tdata(m_axis_tdata2),    // input wire [63 : 0] s_axis_tdata
  .s_axis_tkeep(m_axis_tkeep2),    // input wire [7 : 0] s_axis_tkeep
  .s_axis_tlast(m_axis_tlast2),    // input wire s_axis_tlast
  .m_axis_tvalid(tx_axis_mac_tvalid),  // output wire m_axis_tvalid
  .m_axis_tready(tx_axis_mac_tready),  // input wire m_axis_tready
  .m_axis_tdata(tx_axis_mac_tdata),    // output wire [7 : 0] m_axis_tdata
  .m_axis_tkeep(),    // output wire [0 : 0] m_axis_tkeep
  .m_axis_tlast(tx_axis_mac_tlast)    // output wire m_axis_tlast
);



////////////////////////////////////////////////////////////////////////////////
////////////////////////////////   RX CHANNEL  /////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

axis_data_fifo_0 rx_packet_fifo0 ////////////////////////////////   RX3
(
  .s_axis_aresetn(~core_reset),          // input wire s_axis_aresetn
  .s_axis_aclk(clk_15_625),                // input wire s_axis_aclk
  .s_axis_tvalid(m_axis_tvalid4),            // input wire s_axis_tvalid
  .s_axis_tready(m_axis_tready4),            // output wire s_axis_tready
  .s_axis_tdata(m_axis_tdata4),              // input wire [63 : 0] s_axis_tdata
  .s_axis_tkeep(m_axis_tkeep4),              // input wire [7 : 0] s_axis_tkeep
  .s_axis_tlast(m_axis_tlast4),              // input wire s_axis_tlast
  .s_axis_tuser(1'b0),              // input wire [0 : 0] s_axis_tuser
  .m_axis_tvalid(mac_rx_valid),            // output wire m_axis_tvalid
  .m_axis_tready(1'b1),            // input wire m_axis_tready
  .m_axis_tdata(mac_rx_data),              // output wire [63 : 0] m_axis_tdata
  .m_axis_tkeep(mac_rx_keep),              // output wire [7 : 0] m_axis_tkeep
  .m_axis_tlast(mac_rx_last),              // output wire m_axis_tlast
  .m_axis_tuser(),                          // output wire [0 : 0] m_axis_tuser
  // .axis_data_count(),        // output wire [31 : 0] axis_data_count
  .axis_wr_data_count(),  // output wire [31 : 0] axis_wr_data_count
  .axis_rd_data_count()  // output wire [31 : 0] axis_rd_data_count
);	


axis_data_fifo_1 rx_async_fifo0 ////////////////////////////////   RX2
(
  .s_axis_aresetn(gtx_resetn),          // input wire s_axis_aresetn
  // .m_axis_aresetn(~core_reset),          // input wire m_axis_aresetn
  .s_axis_aclk(rx_mac_aclk),                // input wire s_axis_aclk
  .s_axis_tvalid(m_axis_tvalid3),            // input wire s_axis_tvalid
  .s_axis_tready(m_axis_tready3),            // output wire s_axis_tready
  .s_axis_tdata(m_axis_tdata3),              // input wire [63 : 0] s_axis_tdata
  .s_axis_tkeep(m_axis_tkeep3),              // input wire [7 : 0] s_axis_tkeep
  .s_axis_tlast(m_axis_tlast3),              // input wire s_axis_tlast
  .s_axis_tuser(1'b0),              // input wire [0 : 0] s_axis_tuser
  .m_axis_aclk(clk_15_625),                // input wire m_axis_aclk
  .m_axis_tvalid(m_axis_tvalid4),            // output wire m_axis_tvalid
  .m_axis_tready(m_axis_tready4),            // input wire m_axis_tready
  .m_axis_tdata(m_axis_tdata4),              // output wire [63 : 0] m_axis_tdata
  .m_axis_tkeep(m_axis_tkeep4),              // output wire [7 : 0] m_axis_tkeep
  .m_axis_tlast(m_axis_tlast4),              // output wire m_axis_tlast
  .m_axis_tuser(),                          // output wire [0 : 0] m_axis_tuser
  // .axis_data_count(),        // output wire [31 : 0] axis_data_count
  .axis_wr_data_count(),  // output wire [31 : 0] axis_wr_data_count
  .axis_rd_data_count()  // output wire [31 : 0] axis_rd_data_count
);

axis_dwidth_converter_1 rx_axis_dwidth_converter0 ////////////////////////////////   RX1
(
  .aclk(rx_mac_aclk),                    // input wire aclk
  .aresetn(gtx_resetn),              // input wire aresetn
  .s_axis_tvalid(rx_axis_mac_tvalid),  // input wire s_axis_tvalid
  .s_axis_tready(),  				// output wire s_axis_tready
  .s_axis_tdata(rx_axis_mac_tdata),    // input wire [7 : 0] s_axis_tdata
  .s_axis_tkeep(1'b1),    			// input wire [0 : 0] s_axis_tkeep
  .s_axis_tlast(rx_axis_mac_tlast),    // input wire s_axis_tlast
  .m_axis_tvalid(m_axis_tvalid3),  // output wire m_axis_tvalid
  .m_axis_tready(m_axis_tready3),  // input wire m_axis_tready
  .m_axis_tdata(m_axis_tdata3),    // output wire [63 : 0] m_axis_tdata
  .m_axis_tkeep(m_axis_tkeep3),    // output wire [7 : 0] m_axis_tkeep
  .m_axis_tlast(m_axis_tlast3)    // output wire m_axis_tlast
);	
//----------------------------------------------------------------------------
// Instantiate the Tri-Mode Ethernet MAC core
//----------------------------------------------------------------------------

wire speedis100;
wire speedis10100;

tri_mode_ethernet_mac_0 tri_mode_ethernet_mac_i (
  .gtx_clk              (userclk2),

  // asynchronous reset
  .glbl_rstn            (glbl_rst_intn),
  .rx_axi_rstn          (1'b1),
  .tx_axi_rstn          (1'b1),

  // Receiver Interface
  .rx_statistics_vector (),
  .rx_statistics_valid  (),

  .rx_mac_aclk          (rx_mac_aclk),
  .rx_reset             (rx_reset),
  .rx_axis_mac_tdata    (rx_axis_mac_tdata),
  .rx_axis_mac_tvalid   (rx_axis_mac_tvalid),
  .rx_axis_mac_tlast    (rx_axis_mac_tlast),
  .rx_axis_mac_tuser    (),

  // Transmitter Interface
  .tx_ifg_delay         (8'd0),
  .tx_statistics_vector (),
  .tx_statistics_valid  (),

  .tx_mac_aclk          (tx_mac_aclk),
  .tx_reset             (tx_reset),
  .tx_axis_mac_tdata    (tx_axis_mac_tdata),
  .tx_axis_mac_tvalid   (tx_axis_mac_tvalid),
  .tx_axis_mac_tlast    (tx_axis_mac_tlast),
  .tx_axis_mac_tuser    (1'b0 ),
  .tx_axis_mac_tready   (tx_axis_mac_tready),

  // Flow Control
  .pause_req            (1'b0),
  .pause_val            (16'd0),


  // Speed Control
  .speedis100           (speedis100),// output
  .speedis10100         (speedis10100),// output


  // GMII Interface
  .gmii_txd(gmii_txd),                          // output wire [7 : 0] gmii_txd
  .gmii_tx_en(gmii_tx_en),                      // output wire gmii_tx_en
  .gmii_tx_er(gmii_tx_er),                      // output wire gmii_tx_er
  .gmii_rxd(gmii_rxd),                          // input wire [7 : 0] gmii_rxd
  .gmii_rx_dv(gmii_rx_dv),                      // input wire gmii_rx_dv
  .gmii_rx_er(gmii_rx_er),                      // input wire gmii_rx_er

  // .mdio(phy_mdio),                                  // inout wire mdio
  // .mdc(phy_mdc),                                    // output wire mdc

  // AXI lite interface
  .s_axi_aclk           (userclk2),
  .s_axi_resetn         (s_axi_resetn),
  .s_axi_awaddr         (s_axi_awaddr),
  .s_axi_awvalid        (s_axi_awvalid),
  .s_axi_awready        (s_axi_awready),
  .s_axi_wdata          (s_axi_wdata),
  .s_axi_wvalid         (s_axi_wvalid),
  .s_axi_wready         (s_axi_wready),
  .s_axi_bresp          (s_axi_bresp),
  .s_axi_bvalid         (s_axi_bvalid),
  .s_axi_bready         (s_axi_bready),
  .s_axi_araddr         (s_axi_araddr),
  .s_axi_arvalid        (s_axi_arvalid),
  .s_axi_arready        (s_axi_arready),
  .s_axi_rdata          (s_axi_rdata),
  .s_axi_rresp          (s_axi_rresp),
  .s_axi_rvalid         (s_axi_rvalid),
  .s_axi_rready         (s_axi_rready),

  .mac_irq              ()
   );

wire sgmii_clk_r;
wire sgmii_clk_f;
wire sgmii_clk_en;

wire resetdone;
wire pma_reset_out;
wire mmcm_locked_out;
wire gmii_isolate;


gig_ethernet_pcs_pma_0 gig_ethernet_pcs_pma_i (
  .gtrefclk_p(gtrefclk1_p),                          // input wire gtrefclk_p
  .gtrefclk_n(gtrefclk1_n),                          // input wire gtrefclk_n
  .gtrefclk_out(),                      // output wire gtrefclk_out
  // .gtrefclk_bufg_out(),            // output wire gtrefclk_bufg_out

  .txn(tx_n),                                        // output wire txn
  .txp(tx_p),                                        // output wire txp
  .rxn(rx_n),                                        // input wire rxn
  .rxp(rx_p),                                        // input wire rxp

  .independent_clock_bufg(independent_clock_bufg),  // input wire independent_clock_bufg
  .userclk_out(),                        // output wire userclk_out
  .userclk2_out(userclk2),                      // output wire userclk2_out
  .rxuserclk_out(),                    // output wire rxuserclk_out
  .rxuserclk2_out(),                  // output wire rxuserclk2_out

  .resetdone(resetdone),                            // output wire resetdone
  .pma_reset_out(pma_reset_out),                    // output wire pma_reset_out

  .mmcm_locked_out(mmcm_locked_out),                // output wire mmcm_locked_out

  .sgmii_clk_r(sgmii_clk_r),                        // output wire sgmii_clk_r
  .sgmii_clk_f(sgmii_clk_f),                        // output wire sgmii_clk_f
  .sgmii_clk_en(sgmii_clk_en),                      // output wire sgmii_clk_en

  .gmii_txd(gmii_txd),                              // input wire [7 : 0] gmii_txd
  .gmii_tx_en(gmii_tx_en),                          // input wire gmii_tx_en
  .gmii_tx_er(gmii_tx_er),                          // input wire gmii_tx_er

  .gmii_rxd(gmii_rxd),                              // output wire [7 : 0] gmii_rxd
  .gmii_rx_dv(gmii_rx_dv),                          // output wire gmii_rx_dv
  .gmii_rx_er(gmii_rx_er),                          // output wire gmii_rx_er
  .gmii_isolate(gmii_isolate),                      // output wire gmii_isolate

  .configuration_vector(configuration_vector),      // input wire [4 : 0] configuration_vector

  .an_interrupt(an_interrupt),                      // output wire an_interrupt
  .an_adv_config_vector(an_adv_config_vector),      // input wire [15 : 0] an_adv_config_vector
  .an_restart_config(an_restart_config),            // input wire an_restart_config

  .speed_is_10_100(1'b0),                // input wire speed_is_10_100
  .speed_is_100(1'b0),                      // input wire speed_is_100
  .status_vector(status_vector),                    // output wire [15 : 0] status_vector
  // .reset(~glbl_rst_intn),                                    // input wire reset

  .reset(~rst_n),                                    // input wire reset
  .signal_detect(signal_detect)                    // input wire signal_detect
  // .gt0_qplloutclk_out(),          // output wire gt0_qplloutclk_out
  // .gt0_qplloutrefclk_out()    // output wire gt0_qplloutrefclk_out
);
   
   
   
   
   

  //----------------------------------------------------------------------------
  // Instantiate the AXI-LITE Controller
  //----------------------------------------------------------------------------

tri_mode_ethernet_mac_0_axi_lite_sm axi_lite_controller_0 (
  .s_axi_aclk                   (userclk2),
  .s_axi_resetn                 (s_axi_resetn),

  .mac_speed                    (2'b10),
  .update_speed                 (1'b0),   // may need glitch protection on this..
  .serial_command               (1'b0),
  .serial_response              (),

  .s_axi_awaddr                 (s_axi_awaddr),
  .s_axi_awvalid                (s_axi_awvalid),
  .s_axi_awready                (s_axi_awready),

  .s_axi_wdata                  (s_axi_wdata),
  .s_axi_wvalid                 (s_axi_wvalid),
  .s_axi_wready                 (s_axi_wready),

  .s_axi_bresp                  (s_axi_bresp),
  .s_axi_bvalid                 (s_axi_bvalid),
  .s_axi_bready                 (s_axi_bready),

  .s_axi_araddr                 (s_axi_araddr),
  .s_axi_arvalid                (s_axi_arvalid),
  .s_axi_arready                (s_axi_arready),

  .s_axi_rdata                  (s_axi_rdata),
  .s_axi_rresp                  (s_axi_rresp),
  .s_axi_rvalid                 (s_axi_rvalid),
  .s_axi_rready                 (s_axi_rready)
);


////////////////////////  PHY configure  ////////////////////////

wire phy_mdi; // m : master is FPGA   slave is extral PHY
wire phy_mdo;
wire phy_mdio_ctr;

IOBUF #(
    // .DRIVE(12), // Specify the output drive strength
    // .IBUF_LOW_PWR("TRUE"),  // Low Power - "TRUE", High Performance = "FALSE" 
    // .IOSTANDARD("LVCMOS18"), // Specify the I/O standard
    // .SLEW("SLOW") // Specify the output slew rate
) mdio_IOBUF (
    .T(phy_mdio_ctr),      // 3-state enable input, high=input, low=output
    .IO(phy_mdio),   // Buffer inout port (connect directly to top-level port)
    .I(phy_mdi),     // Buffer input
    .O(phy_mdo)      // Buffer output

);

wire phy_init_done;

phy88E1512_init phy_init (
    .clk (userclk2), 
    .rst (phy_resetn), 
    .mdc (phy_mdc), 
    // .mdio (mdio),
    .mdi(phy_mdi),
    .mdo(phy_mdo),
    .mdio_ctr(phy_mdio_ctr),
    .phy_id (5'd0), 
    .phy_init_done(phy_init_done), 
    .done_ini (1'b1), 
    .phy_speed ()      // 2'b10: 1000Mbps  2'b01: 100Mbps
);

// assign phy_resetn = phy_rstn;





// mac_ila mac_ila (
// 	.clk(clk_15_625), // input wire clk
// 	.probe0(status_vector[1:0]), // input wire [1:0]  probe0  
// 	.probe1(rx_udp_data_length), // input wire [15:0]  probe1 
// 	.probe2(rx_udp_src_port), // input wire [15:0]  probe2 
// 	.probe3(rx_udp_data_error), // input wire [0:0]  probe3 
// 	.probe4(core_reset), // input wire [0:0]  probe4 
// 	.probe5(app_rx_data_valid), // input wire [0:0]  probe5 
// 	.probe6(app_rx_data), // input wire [63:0]  probe6 
// 	.probe7(app_rx_data_keep), // input wire [7:0]  probe7 
// 	.probe8(app_rx_data_last) // input wire [0:0]  probe8
// );



endmodule
